HDFS的java api

回顾:

任务

1.掌握hdfs的java操作
2.理解namenode与datanode的工作机制

目标

1.hdfs的java操作
2.hdfs的组成部分详解

第一节:使用java操作HDFS

1.1 配置开发环境

本课程的开发环境基于windows操作系统来配置的,使用的HDFS版本是hadoop2.7.1.

  1. 下载winutils的windows版本https://github.com/SweetInk/hadoop-common-2.7.1-bin

  2. 配置环境变量

    第一步

    config-env无标题

    第二步

    config-env2

    第三步

    config-env3

  3. 压缩包(hadoop-common-2.7.1-bin)里的hadoop.dll,并拷贝到c:\windows\system32目录中。

  4. 在eclipse环境中创建一个maven项目,并引入依赖。

     
1.2 HDFS控制(Java)

hadoop中关于文件操作类基本上全部是在org.apache.hadoop.fs包中,这些api能够支持的操作包含:打开文件,读写文件,删除文件等。

FileSystem,该类是个抽象类,只能通过来类的get方法得到具体类。get方法存在几个重载版本,常用的是这个:

static FileSystem get(Configuration conf);

1.3 代码演示
 

1.4 FileSystem

我们知道,首先对于任何文件系统都是与当前环境变量紧密联系一起,对于当前 HDFS来说,在创建出当前文件系统实例之前,有必要获得当前的环境变量。代码见下:

Configuration conf = new Configuration();

Configuration 类为用户提供了对当前环境变量的一个实例,其中封装了当前搭载环境的配置,这配置是在我们由 core-site.xml 设置,一般返回值默认的本地系统文件。

而对于 HDFS 为我们提供的 FileSystem,更进一步为我们提供了一套加载当前环境并建立读写路径的 API,使用的方法如下所示:

public static FileSystem get(Configuration conf) throws IOException

public static FileSystem get(URI uri, Configuration conf) throws IOException

第一个方法使用默认的 URI 地址获取当前对象中环境变量加载的文件系统,第二个方法使用传入的 URI 获取路径指定的文件系统。

1.5 FSDataInputStream

我们在对 FSDataInputStream 进行分析之前,将上面例子中代码替换为如下所示:

​ InputStream fis = fs.open(inPath);

程序依旧可以正常运行。

 
 

上述代码是重复读取指定 HDFS 中文件的内容,第一次读取结束后,调用 seek(0)方法从而返回文件开始处重新进行数据读取。

1.6 FSDataOutputStream
 

FSDataOutputStream 也是继承自 OutoutStream 的一个子类,专用为 FileSystem 提供文件的输出流。然后可以使用 OutoutStream 中的 write 方法对字节数组进行写操作。

 

有一个是Progressable progress 的形参, Progressable 接口如下所示:

 

Progressable 接口中只有一个 progress 方法,每次在 64K 的文件写入既定的输入流以后,调用一次 progress 方法,这给我们提供了很好一次机会,可以将输出进度显示,代码如下:

 

注意: FSDataOutputStream 与 FSDataInputStream 类似,也有 getPos 方法,返回是文件内以读取的长度。但是不同之处在于, FSDataOutputStream 不能够使用 seek 方法对文件重新定位。

第二节:NameNode详解

2.1 NameNode的功能
2.2 NameNode 启动过程

namenode-start

2.3 NameNode元数据管理

metadata-manager2

metadate-manager

  1. Secondary NN通知NameNode切换editlog。
  2. Secondary NN从NameNode 获得fsimage和editlog(通过http方式)。
  3. Secondary NN将fsimage载入内存,然后开始合并editlog。
  4. Secondary NN 将新的fsimage发回给NameNode NameNode 用新的fsimage替换旧的fsimage
2.4 安全模式

​ 安全模式下,集群属于只读状态。但是严格来说,只是保证HDFS元数据信息的访问,而不保证文件的访问,因为文件的组成Block信息此时NameNode还不一定已经知道了。所以只有NameNode已了解了Block信息的文件才能独到。而安全模式下任何对HDFS有更新的操作都会失败。

​ 对于全新创建的HDFS集群,NameNode启动后不会进入安全模式,因为没有Block信息。

安全模式相关命令

第三节 DataNode详解

3.1 Datanode功能

​ 存储管理用户的文件块数据定期向namenode汇报自身所持有的block信息(通过心跳信息上报汇报的目的是,namenode如果长时间接收不到一个datanode的心跳后,说明该datanode宕机了,该datanode的数据块就被namdenode拿不到了,需要从其他机上拿该datanode的数据块副本。

3.2 Datanode掉线判断时限参数

​ datanode进程死亡或者网络故障造成datanode无法与namenode通信,namenode不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长。HDFS默认的超时时长为10分钟+30秒。如果定义超时时间为timeout,则超时时长的计算公式为:

​ timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval。

​ 而默认的heartbeat.recheck.interval 大小为5分钟,dfs.heartbeat.interval默认为3秒。

需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的单位为毫秒,dfs.heartbeat.interval的单位为秒。所以,举个例子,如果heartbeat.recheck.interval设置为5000(毫秒),dfs.heartbeat.interval设置为3(秒,默认),则总的超时时间为40秒。